#pragma once

// Copyright (c) 2010 Manuel Peinado Gallego <manuel.peinado@gmail.com>
// Distributed under the MIT license

// TextureManager.h : interface of the TextureManager class
//

#include <set>
#include "Texture.h"
#include "Common.h"
class TextureManager;


class TextureListener 
{
public:
    virtual void onTextureAddedOrRemoved(TextureManager*, Texture*) { }
//    virtual void onTextureAppearanceChanged(TextureManager*, Texture*) { }
};


class TextureManager
{
private:
    
    typedef std::set<ref<Texture> > TextureSet;

public:

    TextureManager();

    // - - -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  - 

    void registerTexture(ref<Texture> mat);

    // - - -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  - 
    
    // Deletes all textures
    void clear();

    // - - -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  - 

    // Return NULL ptr if Texture does not exist
    Texture* getTextureById(size_t id) const;
    Texture* getTextureByName(const std::wstring& name) const;
    static ref<Texture> getDefaultTexture();

    // - - -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  - 

    std::wstring generateNameFromPrefix(const std::wstring& prefix) const;
    
    // - - -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  - 

    typedef TextureSet::const_iterator TextureIt;
    TextureIt beginTextures();
    TextureIt endTextures();
    size_t getTextureCount() const;

    // - - -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  - 

    // This will be called by the Textures that are registered with this 
    // manager when one of their parameters change. The manager, in turn,
    // will notifiy all its listeners

    //void notifyTextureAppearanceChanged(Texture* mat);

    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 

    void addTextureListener(TextureListener* listener);
    void removeTextureListener(TextureListener* listener);

    // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    
    ref<Texture> simplePngLoad(const std::string& fileName);
    ref<Texture> simpleJpgLoad(const std::string& fileName);

private:

    // - - -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  - 

    ref<Texture> simpleLoad(const std::string& fileName, const char* fileExt);

    // - - -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  - 

    bool m_initialized;

    // - - -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  - 

    TextureSet m_textures;

    // - - -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  - 

    void addDefaultTexture();

    // We use set<> to avoid duplicates
    typedef std::set<TextureListener*>::iterator ListenerIt;
    std::set<TextureListener *> m_listeners;
    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 
};

